/**
 * 
 */
package view;

import static com.google.common.base.Preconditions.checkNotNull;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

import model.HeatMapData;

import com.alee.laf.button.WebButton;
import com.alee.laf.label.WebLabel;
import com.alee.laf.scroll.WebScrollPane;

import controller.Controls;

/**
 * @author Jamada
 *
 */
public class ClusterListPanel extends JPanel {
    /**
     * Serial Version ID.
     */
    private static final long serialVersionUID = 8447145240280172772L;
    
    private static final Dimension ONE_CLUSTER_SIZE = new Dimension(400, 100);
 
    /**
     * 
     */
    private final List<HeatMapData> heatMapDataClusters;
    /**
     * 
     */
    private final String panelTitle;
    /**
     * 
     */
    private Controls controller;
    /**
     * 
     * @param heatMapClusters
     */
    public ClusterListPanel(final Controls controls, final List<HeatMapData> heatMapClusters, final String title) {
        this.heatMapDataClusters = heatMapClusters;
        this.panelTitle = title;
        this.controller = controls;
        this.setBackground(Color.WHITE);
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        setupGrid();
    }

    private void setupGrid() {
        JPanel gridPanel = new JPanel();
        gridPanel.setOpaque(false);
        GridLayout grid = new GridLayout(this.heatMapDataClusters.size(), 1);
        //grid.setHgap(5);
        grid.setVgap(10);
        gridPanel.setLayout(grid);
        
        for (int i = 0; i < this.heatMapDataClusters.size(); i++) {
            //Individual data result
            JPanel outerPanel = new JPanel();
            
            outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.X_AXIS));
            JPanel innerGrid = new JPanel();

            GridLayout inner = new GridLayout(3, 1);
            innerGrid.setLayout(inner);
            WebLabel signalLabel = new WebLabel("Average Signal Strength: " + new DecimalFormat("#.###").format(this.heatMapDataClusters.get(i).getAvgSignal()));
            WebLabel proteinLabel = new WebLabel("Number of Proteins: " + this.heatMapDataClusters.get(i).getYValues().length);
            WebLabel compoundLabel = new WebLabel("Number of Compounds: " + this.heatMapDataClusters.get(i).getXValues().length);
            signalLabel.setMargin(0, 10, 0, 0);
            proteinLabel.setMargin(0, 10, 0, 0);
            compoundLabel.setMargin(0, 10, 0, 0);
            innerGrid.add(signalLabel);
            innerGrid.add(proteinLabel);
            innerGrid.add(compoundLabel);
            outerPanel.add(innerGrid);   
            outerPanel.add(makeHeatMapButton(i + 1, this.heatMapDataClusters.get(i)));
 
            outerPanel.setMaximumSize(ONE_CLUSTER_SIZE);
            outerPanel.setPreferredSize(ONE_CLUSTER_SIZE);
            outerPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED), 
                                                              BorderFactory.createBevelBorder(BevelBorder.LOWERED)));

            innerGrid.setOpaque(false);
            outerPanel.setOpaque(false);
            JPanel outerHolder = new JPanel();
            outerHolder.add(outerPanel);
            outerHolder.setOpaque(false);
            gridPanel.add(outerHolder);
        }
        gridPanel.setMaximumSize(new Dimension(460, 400));
        gridPanel.setBorder(BorderFactory.createEmptyBorder(0,20,20,20));
        JLabel listTitle = new JLabel();
        listTitle.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 20));
        listTitle.setText(panelTitle);
        listTitle.setAlignmentX(CENTER_ALIGNMENT);
        listTitle.setBorder(BorderFactory.createEmptyBorder(25, 0, 0, 0));
        listTitle.setOpaque(false);
        //JScrollPane scroll = new JScrollPane(gridPanel);
        WebScrollPane scroll = new WebScrollPane(gridPanel);
        scroll.getViewport().setOpaque(false);
        scroll.setOpaque(false);
        scroll.getWebUI().setDrawBorder(false);
        scroll.setMaximumSize(new Dimension(500, 1000));
        this.add(listTitle);
        this.add(scroll);      
    }
    
    public JButton makeHeatMapButton(final int clusterNumber, final HeatMapData heatMapData) {
        WebButton genHeatMapButton = new WebButton("Generate Cluster " + clusterNumber + " Heat Map");

        genHeatMapButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent the_event) {
            	final String fileName = controller.saveHeatMapToFile(heatMapData, "cluster_" + clusterNumber);  
            	
                //Label 
                BufferedImage samplePicture = checkNotNull(getImageFromFile(fileName));
                JLabel imageLabel = new JLabel(new ImageIcon(samplePicture));
                WebScrollPane scroll = new WebScrollPane(imageLabel);
                scroll.getViewport().setOpaque(false);
                scroll.setOpaque(false);
                scroll.getWebUI().setDrawBorder(false);
                controller.displayHeatMapImage("Heat Map Images", scroll);
            }
        });
        genHeatMapButton.setAlignmentX(CENTER_ALIGNMENT);
        return genHeatMapButton;
    }
    
    private BufferedImage getImageFromFile(String fileLocation) {
        BufferedImage result = null;
        try {
            result = ImageIO.read(new File(fileLocation));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}
